﻿/*************************************
 * Creator:SW-PeiYang
 * DateTime:2024/9/10 8:54:35
 * Description:<Description>
 * CopyRight:中广核研究院有限公司
 * ***********************************/

using Autofac;
using Autofac.Core;
using SunnyPaine.Autofac.Extension.Stereotype.Attributes;
using System.Reflection;

namespace SunnyPaine.Autofac.Extension.Stereotype.Selector
{
    /// <summary>
    /// 根据实例的名称注入。
    /// </summary>
    public class ResourcePropertySelector : IPropertySelector
    {
        /// <summary>
        /// 属性过滤。
        /// </summary>
        /// <param name="propertyInfo"></param>
        /// <param name="instance"></param>
        /// <returns></returns>
        public bool InjectProperty(PropertyInfo propertyInfo, object instance)
        {
            foreach (CustomAttributeData item in propertyInfo.CustomAttributes)
            {
                if (item.AttributeType == typeof(ResourceAttribute))
                {
                    ResourceAttribute resourceAttribute = propertyInfo.GetCustomAttribute<ResourceAttribute>();
                    if (resourceAttribute.Name != null)
                    {
                        object propertyInstance = ServiceLocator.Container.ResolveNamed(resourceAttribute.Name, propertyInfo.PropertyType);
                        propertyInfo.SetValue(instance, propertyInstance);
                    }
                    else
                    {
                        object propertyInstance = null;
                        if (ServiceLocator.Container.IsRegistered(propertyInfo.PropertyType))
                        {
                            propertyInstance = ServiceLocator.Container.Resolve(propertyInfo.PropertyType);
                        }
                        else if (ServiceLocator.Container.IsRegisteredWithName(propertyInfo.Name, propertyInfo.PropertyType))
                        {
                            propertyInstance = ServiceLocator.Container.ResolveNamed(propertyInfo.Name, propertyInfo.PropertyType);
                        }
                        if (propertyInstance != null)
                        {
                            object originalPropertyInstance;
                            string typeName = propertyInstance.GetType().FullName;
                            if (typeName.StartsWith("Castle.Proxies") && typeName.EndsWith("Proxy"))
                            {
                                originalPropertyInstance = Castle.DynamicProxy.ProxyUtil.GetUnproxiedInstance(propertyInstance);
                            }
                            else
                            {
                                originalPropertyInstance = propertyInstance;
                            }
                            propertyInfo.SetValue(instance, originalPropertyInstance);
                        }
                    }
                    //必须返回false，如果为true将会被视为自动类型注入
                    //在 ResourcePropertySelector里不需要自动类型注入，因为AutowirePropertySelector已经实现了，本selector的目的是根据名称注入
                    //注入过程已经在 propertyInfo.SetValue(instance, originalPropertyInstance); 这句完成了
                    return false;
                }
            }
            return false;
        }
    }
}
